home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / dev / sun3.md / devTtyAttach.c < prev    next >
C/C++ Source or Header  |  1991-05-03  |  10KB  |  401 lines

  1. /* 
  2.  * devTtyAttach.c --
  3.  *
  4.  *    This file manages the configuration of Z8530 chips on Sun-3
  5.  *    and Sun-4 workstations, and provides glue to attach the device
  6.  *    drivers for those chips to standard Sprite devices like
  7.  *    /dev/console and /dev/serialA.
  8.  *
  9.  * Copyright 1989 Regents of the University of California
  10.  * Permission to use, copy, modify, and distribute this
  11.  * software and its documentation for any purpose and without
  12.  * fee is hereby granted, provided that the above copyright
  13.  * notice appear in all copies.  The University of California
  14.  * makes no representations about the suitability of this
  15.  * software for any purpose.  It is provided "as is" without
  16.  * express or implied warranty.
  17.  */
  18.  
  19. #ifndef lint
  20. static char rcsid[] = "$Header: /sprite/src/kernel/dev/sun3.md/RCS/devTtyAttach.c,v 9.6 91/05/03 16:17:56 jhh Exp $ SPRITE (Berkeley)";
  21. #endif /* not lint */
  22.  
  23. #include "sprite.h"
  24. #include "stdio.h"
  25. #include "console.h"
  26. #include "devAddrs.h"
  27. #include "mouse.h"
  28. #include "mach.h"
  29. #include "machMon.h"
  30. #include "tty.h"
  31. #include "z8530.h"
  32. #ifndef sun2
  33. #include <sys/types.h>
  34. #include <mon/eeprom.h>
  35. #endif
  36.  
  37. /*
  38.  * Forward references to procedures declared in this file:
  39.  */
  40.  
  41. static int    NullOutputChar();
  42. static int    TtyInterrupt();
  43.  
  44. /*
  45.  * Pre-initialized data structures for three of the four channels in
  46.  * the two Z8530 SCC chips (see devMouse.c for the fourth).
  47.  */
  48.  
  49. static DevTty ttys[3];
  50.  
  51. static DevZ8530 keyboard = {
  52.     "keyboard",                    /* name */
  53.     (DevZ8530Device *) DEV_KBD_ADDR,        /* address */
  54.     &ttys[0],                    /* ttyPtr */
  55.     DEV_UART_VECTOR,                /* vector */
  56.     1200,                    /* baud */
  57.     WRITE3_RX_8BIT,                /* wr3 */
  58.     WRITE5_TX_8BIT,                /* wr5 */
  59.     DevConsoleInputProc,            /* inputProc */
  60.     (ClientData) &ttys[0],            /* inputData */
  61.     NullOutputChar,                /* outputProc */
  62.     (ClientData) &ttys[0],            /* outputData */
  63.     0,                        /* oldRr0 */
  64.     Z_CHANNEL_A | Z_INACTIVE            /* flags */
  65. };
  66.  
  67. static DevZ8530 serialA = {
  68.     "serialA",                    /* name */
  69.     (DevZ8530Device *) DEV_SERIALA_ADDR,    /* address */
  70.     &ttys[1],                    /* ttyPtr */
  71.     DEV_UART_VECTOR,                /* vector */
  72.     9600,                    /* baud */
  73.     WRITE3_RX_8BIT,                /* wr3 */
  74.     WRITE5_TX_8BIT,                /* wr5 */
  75.     DevTtyInputChar,                /* inputProc */
  76.     (ClientData) &ttys[1],            /* inputData */
  77.     DevTtyOutputChar,                /* outputProc */
  78.     (ClientData) &ttys[1],            /* outputData */
  79.     0,                        /* oldRr0 */
  80.     Z_CHANNEL_A | Z_INACTIVE            /* flags */
  81. };
  82.  
  83. static DevZ8530 serialB = {
  84.     "serialB",                    /* name */
  85.     (DevZ8530Device *) DEV_SERIALB_ADDR,    /* address */
  86.     &ttys[2],                    /* ttyPtr */
  87.     DEV_UART_VECTOR,                /* vector */
  88.     9600,                    /* baud */
  89.     WRITE3_RX_8BIT,                /* wr3 */
  90.     WRITE5_TX_8BIT,                /* wr5 */
  91.     DevTtyInputChar,                /* inputProc */
  92.     (ClientData) &ttys[2],            /* inputData */
  93.     DevTtyOutputChar,                /* outputProc */
  94.     (ClientData) &ttys[2],            /* outputData */
  95.     0,                        /* oldRr0 */
  96.     Z_CHANNEL_B | Z_INACTIVE            /* flags */
  97. };
  98.  
  99. /*
  100.  * The following variable is filled in with the unit that should
  101.  * be used whenever "/dev/console" is opened (may be a serial unit
  102.  * if the machine doesn't have a keyboard+display).
  103.  */
  104.  
  105. static int consoleUnit = 0;
  106.  
  107. /*
  108.  *----------------------------------------------------------------------
  109.  *
  110.  * DevTtyInit --
  111.  *
  112.  *    Called during bootstrapping to initialize terminal-related
  113.  *    things.
  114.  *
  115.  * Results:
  116.  *    None.
  117.  *
  118.  * Side effects:
  119.  *    Resets serial devices and performs other initialization.
  120.  *
  121.  *----------------------------------------------------------------------
  122.  */
  123.  
  124. void
  125. DevTtyInit()
  126. {
  127.     char promConsoleType;
  128.  
  129.     /*
  130.      * Figure out whether this machine has a display for a console or
  131.      * just a terminal on a serial line.
  132.      */
  133.  
  134. #ifndef sun2
  135. #ifdef sun4c
  136.     promConsoleType = *romVectorPtr->inSource;
  137. #else
  138.     promConsoleType = ((struct eeprom *) EEPROM_BASE)->ee_diag.eed_console;
  139. #endif /* sun4c */
  140.     switch (promConsoleType) {
  141.     case EED_CONS_TTYA:
  142.         consoleUnit = 1;
  143.         break;
  144.     case EED_CONS_TTYB:
  145.         consoleUnit = 2;
  146.         break;
  147.     case EED_CONS_BW:
  148.     case EED_CONS_COLOR:
  149.     case EED_CONS_P4:
  150.         consoleUnit = 0;
  151.         break;
  152.     default:
  153.         printf("Warning: %s 0x%x\n",
  154.             "Dev_TtyAttach couldn't identify console type",
  155.             promConsoleType);
  156.         break;
  157.     }
  158. #endif /* sun2 */
  159.  
  160.     /*
  161.      * Reset the devices.
  162.      */
  163.  
  164.     DevZ8530RawProc(&keyboard, TD_RAW_SHUTDOWN, 0, (char *) NULL,
  165.         0, (char *) NULL);
  166.     DevZ8530RawProc(&serialA, TD_RAW_SHUTDOWN, 0, (char *) NULL,
  167.         0, (char *) NULL);
  168.     DevZ8530RawProc(&serialB, TD_RAW_SHUTDOWN, 0, (char *) NULL,
  169.         0, (char *) NULL);
  170.     DevMouseInit();
  171.  
  172. #ifdef sun4
  173.     Mach_SetHandler(12, TtyInterrupt, (ClientData) 0);
  174. #else
  175.     Mach_SetHandler(DEV_UART_VECTOR, TtyInterrupt, (ClientData) 0);
  176. #endif
  177.     Mach_MonStopNmi();
  178. }
  179.  
  180. /*
  181.  *----------------------------------------------------------------------
  182.  *
  183.  * DevTtyAttach --
  184.  *
  185.  *    Given a unit number, return the DevTty for the unit, properly
  186.  *    initialized.  This procedure is called as part of the open
  187.  *    sequence for a terminal.
  188.  *
  189.  * Results:
  190.  *    The return value is a pointer to a DevTty for the given unit,
  191.  *    with some of its fields filled in (see devTty.h for details).
  192.  *    If the unit number is bad, then NULL is returned.
  193.  *
  194.  * Side effects:
  195.  *    Device-specific data structures get initialized.
  196.  *
  197.  *----------------------------------------------------------------------
  198.  */
  199.  
  200. DevTty *
  201. DevTtyAttach(unit)
  202.     int unit;            /* Unit number for device. */
  203. {
  204.     register DevTty *ttyPtr;
  205.  
  206.     if ((unit > 2) || (unit < 0)) {
  207.     return NULL;
  208.     }
  209.  
  210.     /*
  211.      * If the console is one of the serial units, then disallow the
  212.      * serial unit for any use other than console.  Otherwise the
  213.      * wait tokens will get confused (two different wait tokens from
  214.      * higher-level software, but only one stored in the tty structure).
  215.      */
  216.  
  217.     if ((unit != 0) && (unit == consoleUnit)) {
  218.     return NULL;
  219.     }
  220.     
  221.     if (unit == 0) {
  222.     unit = consoleUnit;
  223.     }
  224.     ttyPtr = &ttys[unit];
  225.  
  226.     /*
  227.      * If the terminal is already open then there's nothing more to
  228.      * do;  otherwise, initialize the information relating to the
  229.      * unit.
  230.      */
  231.  
  232.     if (ttyPtr->openCount > 0) {
  233.     return ttyPtr;
  234.     }
  235.     ttyPtr->rawProc = DevZ8530RawProc;
  236.     ttyPtr->activateProc = DevZ8530Activate;
  237.     ttyPtr->inputProc = (void (*)()) NIL;
  238.     ttyPtr->inputData = (ClientData) 0;
  239.     if (unit == consoleUnit) {
  240.     ttyPtr->consoleFlags = DEV_TTY_IS_CONSOLE;
  241.     } else {
  242.     ttyPtr->consoleFlags = 0;
  243.     }
  244.  
  245.     switch (unit) {
  246.  
  247.     /*
  248.      * Unit 0 is the display+keyboard, which serves as console
  249.      * if it exists.
  250.      */
  251.  
  252.     case 0:
  253.         ttyPtr->rawProc = DevConsoleRawProc;
  254.         ttyPtr->rawData = (ClientData) &keyboard;
  255.         break;
  256.  
  257.     /*
  258.      * Unit 1 is serialA.
  259.      */
  260.  
  261.     case 1:
  262.         ttyPtr->rawData = (ClientData) &serialA;
  263.         break;
  264.  
  265.     /*
  266.      * Unit 2 is serialB.
  267.      */
  268.  
  269.     case 2:
  270.         ttyPtr->rawData = (ClientData) &serialB;
  271.         break;
  272.     }
  273.     return ttyPtr;
  274. }
  275.  
  276. /*
  277.  *----------------------------------------------------------------------
  278.  *
  279.  * DevGrabKeyboard --
  280.  *
  281.  *    This procedure is a special hack to allow events from the
  282.  *    keyboard to be redirected back and forth between /dev/console
  283.  *    and /dev/event.  DevGrabKeyboard is called to redirect input
  284.  *    keystrokes away from their normal target (/dev/console) to
  285.  *    some other place.
  286.  *
  287.  * Results:
  288.  *    The return value is a pointer to the DevZ8530 structure for
  289.  *    the keyboard (in case the caller should need to use some of
  290.  *    its fields).
  291.  *
  292.  * Side effects:
  293.  *    From now on, inputProc will be used to process input characters
  294.  *    from the keyboard and outpuProc will be used to supply output
  295.  *    characters to the keyboard.
  296.  *
  297.  *----------------------------------------------------------------------
  298.  */
  299.  
  300. DevZ8530 *
  301. DevGrabKeyboard(inputProc, inputData, outputProc, outputData)
  302.     void (*inputProc)();        /* Procedure for devTty.c to call
  303.                      * to process input characters
  304.                      * at background level. */
  305.     ClientData inputData;        /* Argument to pass to inputProc. */
  306.     int (*outputProc)();        /* Interrupt-level procedure to
  307.                      * provide next output character. */
  308.     ClientData outputData;        /* Argument to pass to outputProc. */
  309. {
  310.     ttys[0].inputProc = inputProc;
  311.     ttys[0].inputData = inputData;
  312.     keyboard.outputProc = outputProc;
  313.     keyboard.outputData = outputData;
  314.     return &keyboard;
  315. }
  316.  
  317. /*
  318.  *----------------------------------------------------------------------
  319.  *
  320.  * DevReleaseKeyboard --
  321.  *
  322.  *    This procedure is also part of the special hack to allow events
  323.  *    from the keyboard to be redirected back and forth between
  324.  *    /dev/console and /dev/event.  When the event device is closed
  325.  *    for the last time, this procedure is called to redirect keyboard
  326.  *    input back to /dev/console.
  327.  *
  328.  * Results:
  329.  *    None.
  330.  *
  331.  * Side effects:
  332.  *    Keyboard input goes to /dev/console again.
  333.  *
  334.  *----------------------------------------------------------------------
  335.  */
  336.  
  337. void
  338. DevReleaseKeyboard()
  339. {
  340.     ttys[0].inputProc = (void (*)()) NIL;
  341.     ttys[0].inputData = (ClientData) 0;
  342.     keyboard.outputProc = NullOutputChar;
  343.     keyboard.outputData = (ClientData) &ttys[0];
  344. }
  345.  
  346. /*
  347.  *----------------------------------------------------------------------
  348.  *
  349.  * TtyInterrupt --
  350.  *
  351.  *    This procedure is called whenever an interrupt occurs on
  352.  *    one of the Z8530 chips.  Various models of Sun's don't
  353.  *    handle "real" interrupt vectors from the UART chips, so the
  354.  *    safest thing is to auto-vector them all through this procedure.
  355.  *
  356.  * Results:
  357.  *    None.
  358.  *
  359.  * Side effects:
  360.  *    Each chip's interrupt handler gets invoked in turn to
  361.  *    process input and output characters for that chip.
  362.  *
  363.  *----------------------------------------------------------------------
  364.  */
  365.  
  366. static int
  367. TtyInterrupt()
  368. {
  369.     DevZ8530Interrupt((ClientData)&keyboard);
  370.     DevZ8530Interrupt((ClientData)&serialA);
  371.     DevZ8530Interrupt((ClientData)&serialB);
  372.     DevMouseInterrupt();
  373.     return 0;
  374. }
  375.  
  376. /*
  377.  *----------------------------------------------------------------------
  378.  *
  379.  * NullOutputChar --
  380.  *
  381.  *    This procedure is entered as the outputProc field of
  382.  *    DevZ8530 structures when the device is not used for
  383.  *    output.
  384.  *
  385.  * Results:
  386.  *    Always returns -1, which means "no output characters available".
  387.  *
  388.  * Side effects:
  389.  *    None.
  390.  *
  391.  *----------------------------------------------------------------------
  392.  */
  393.  
  394. /* ARGSUSED */
  395. static int
  396. NullOutputChar(clientData)
  397.     ClientData clientData;        /* Not used. */
  398. {
  399.     return -1;
  400. }
  401.